package com.southwind.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.southwind.entity.User;
import com.southwind.form.loginForm;
import com.southwind.service.UserService;
import com.southwind.util.JwtUtil;
import com.southwind.util.Result;
import com.wf.captcha.SpecCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class loginController {


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private JwtUtil jwtUtil;



    /**
     * 验证码生成
     * @return
     */
    @GetMapping("/captcha")
    public Result captcha(){
        //生成验证码
        log.info("开始生成验证码");
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);
        String code = specCaptcha.text().toLowerCase();
        String uuid = IdUtil.simpleUUID();

        //存入redis并设置过期时间为2分钟
        redisTemplate.opsForValue().set(uuid,code,120,TimeUnit.SECONDS);

        Map<String, String> map = new HashMap<String, String>(3);
        map.put("uuid", uuid);
        map.put("code", code);
        map.put("captcha", specCaptcha.toBase64());
        return Result.ok().put("data",map);
    }

    /**
     * 用户登录
     * @param loginForm
     * @param session
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody loginForm loginForm, HttpSession session){
        log.info("登录逻辑");
        //验证码校验
        String code=(String) this.redisTemplate.opsForValue().get(loginForm.getUuid());
        //判断验证码是否存在
        if (code == null){
            return Result.ok().put("status","fail").put("data","验证码已过期");
        }
        //判断验证码是否正确
        if (!code.equals(loginForm.getCaptcha())){
            return Result.ok().put("status","fail").put("data","验证码错误");
        }
        //判断用户名是否正确
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",loginForm.getUsername());
        User user = this.userService.getOne(queryWrapper);
        if (user==null){
            return Result.ok().put("status","fail").put("data","用户名不存在");
        }
        //判断密码是否正确
        String password = SecureUtil.sha256(loginForm.getPassword());
        if (!password.equals(user.getPassword())){
            return Result.ok().put("status","fail").put("data","密码错误");
        }
        //验证用户状态是否可用
        if (user.getStatus() ==0){
            return Result.ok().put("status","fail").put("data","当前账号已被锁定");
        }
        //登陆成功
        session.setAttribute("user",user);
        log.info("user",user);
        //创建token
        String token = this.jwtUtil.createToken(String.valueOf(user.getUserId()));
        this.redisTemplate.opsForValue().set("communityUser-"+user.getUserId(),token,jwtUtil.getExpire());
        Map<String,Object> map=new HashMap<>();
        map.put("token",token);
        map.put("expire",jwtUtil.getExpire());
        return Result.ok().put("status","sueecss").put("data",map);

    }

    /**
     * 校验token，实现登录
     * @param request
     * @return
     */
    @GetMapping("/checkToken")
    public Result checkToken(HttpServletRequest request){
        String token = request.getHeader("token");
        boolean result = this.jwtUtil.checkToken(token);
        if (result) return Result.ok().put("status","ok");
        return Result.ok().put("status","error");
    }

    @PostMapping("/logout")
    public Result logout(HttpSession session){
        session.invalidate();
        return Result.ok();
    }

}
